package export

import (
	"encoding/csv"
	"fmt"
	"os"
	"path/filepath"
	"time"
	"user_srv/handler/models"
)

// ExportFormat 定义导出格式类型
type ExportFormat string

const (
	// FormatCSV CSV文件格式
	FormatCSV ExportFormat = "csv"
	// FormatExcel Excel文件格式
	FormatExcel ExportFormat = "excel"
)

// ExportData 导出数据到指定格式
// dataType: 数据类型，如"user"、"invoice"、"consumption"
// format: 导出格式，可以是FormatCSV或FormatExcel
// fileName: 导出的文件名
// data: 要导出的数据，需要根据dataType传入对应类型的切片
// 返回值: 成功返回文件路径，失败返回错误
func ExportData(dataType string, format ExportFormat, fileName string, data interface{}) (string, error) {
	// 创建导出目录
	exportDir := filepath.Join("exports")
	if err := os.MkdirAll(exportDir, 0755); err != nil {
		return "", fmt.Errorf("创建导出目录失败: %w", err)
	}

	// 生成文件路径
	filePath := filepath.Join(exportDir, fileName)

	// 根据格式导出数据
	if format == FormatCSV || format == FormatExcel {
		// 对于CSV和Excel格式，目前都使用CSV格式导出
		// 注意：Excel格式导出只是文件扩展名不同，内容仍为CSV格式
		return exportToCSV(filePath, dataType, data)
	}

	return "", fmt.Errorf("不支持的导出格式: %s", format)
}

// exportToCSV 将数据导出为CSV格式
// filePath: CSV文件保存路径
// dataType: 数据类型
// data: 要导出的数据
// 返回值: 成功返回空字符串，失败返回错误
func exportToCSV(filePath string, dataType string, data interface{}) (string, error) {
	// 创建CSV文件
	file, err := os.Create(filePath)
	if err != nil {
		return "", fmt.Errorf("创建CSV文件失败: %w", err)
	}
	defer file.Close()

	writer := csv.NewWriter(file)
	defer writer.Flush()

	// 根据数据类型写入CSV
	switch dataType {
	case "user":
		// 断言数据为用户切片类型
		users, ok := data.([]models.User)
		if !ok {
			return "", fmt.Errorf("无效的用户数据类型")
		}
		return writeUserCSV(writer, users)
	case "invoice":
		// 断言数据为发票切片类型
		invoices, ok := data.([]models.Invoice)
		if !ok {
			return "", fmt.Errorf("无效的发票数据类型")
		}
		return writeInvoiceCSV(writer, invoices)
	case "consumption":
		// 断言数据为消费记录切片类型
		consumptions, ok := data.([]models.UserConsumptionInformation)
		if !ok {
			return "", fmt.Errorf("无效的消费记录数据类型")
		}
		return writeConsumptionCSV(writer, consumptions)
	default:
		return "", fmt.Errorf("不支持的数据类型: %s", dataType)
	}
}

// writeUserCSV 写入用户数据到CSV
// writer: CSV写入器
// users: 用户数据切片
// 返回值: 成功返回空字符串，失败返回错误
func writeUserCSV(writer *csv.Writer, users []models.User) (string, error) {
	// 写入标题行
	headers := []string{"ID", "昵称", "真实姓名", "身份证号", "性别", "地址", "注册时间", "登录时间"}
	if err := writer.Write(headers); err != nil {
		return "", fmt.Errorf("写入CSV标题失败: %w", err)
	}

	// 写入数据行
	for _, user := range users {
		row := []string{
			fmt.Sprintf("%d", user.Id), // 用户ID
			user.NickName,              // 昵称
			user.RealName,              // 真实姓名
			user.IdCard,                // 身份证号
			user.Sex,                   // 性别
			user.Address,               // 地址
			user.UserRegisterTime.Format("2006-01-02 15:04:05"), // 注册时间
			user.UserLoginTime.Format("2006-01-02 15:04:05"),    // 登录时间
		}
		if err := writer.Write(row); err != nil {
			return "", fmt.Errorf("写入CSV数据失败: %w", err)
		}
	}

	return "", nil
}

// writeInvoiceCSV 写入发票数据到CSV
// writer: CSV写入器
// invoices: 发票数据切片
// 返回值: 成功返回空字符串，失败返回错误
func writeInvoiceCSV(writer *csv.Writer, invoices []models.Invoice) (string, error) {
	// 写入标题行
	headers := []string{"ID", "名称", "税号", "地址", "手机", "开户银行", "银行账户", "创建时间"}
	if err := writer.Write(headers); err != nil {
		return "", fmt.Errorf("写入CSV标题失败: %w", err)
	}

	// 写入数据行
	for _, invoice := range invoices {
		row := []string{
			fmt.Sprintf("%d", invoice.Id),                   // 发票ID
			invoice.Name,                                    // 名称
			invoice.TaxIdentificationNumber,                 // 税号
			invoice.Address,                                 // 地址
			invoice.Mobile,                                  // 手机
			invoice.BankOfDeposit,                           // 开户银行
			invoice.BankAccount,                             // 银行账户
			invoice.CreatedAt.Format("2006-01-02 15:04:05"), // 创建时间
		}
		if err := writer.Write(row); err != nil {
			return "", fmt.Errorf("写入CSV数据失败: %w", err)
		}
	}

	return "", nil
}

// writeConsumptionCSV 写入消费记录数据到CSV
// writer: CSV写入器
// consumptions: 消费记录数据切片
// 返回值: 成功返回空字符串，失败返回错误
func writeConsumptionCSV(writer *csv.Writer, consumptions []models.UserConsumptionInformation) (string, error) {
	// 写入标题行
	headers := []string{"ID", "用户ID", "支付编号", "事件", "价格时间", "订单编号", "礼品金额", "充值本金", "总充值金额", "退款金额", "总订单价格", "月度订单支付金额"}
	if err := writer.Write(headers); err != nil {
		return "", fmt.Errorf("写入CSV标题失败: %w", err)
	}

	// 写入数据行
	for _, consumption := range consumptions {
		row := []string{
			fmt.Sprintf("%d", consumption.Id),                        // 记录ID
			fmt.Sprintf("%d", consumption.UserId),                    // 用户ID
			fmt.Sprintf("%d", consumption.PayNo),                     // 支付编号
			consumption.Event,                                        // 事件
			consumption.PriceTime.Format("2006-01-02 15:04:05"),      // 价格时间
			consumption.OrderNo,                                      // 订单编号
			consumption.GiftAmount,                                   // 礼品金额
			consumption.RechargeAmountPrincipal,                      // 充值本金
			fmt.Sprintf("%d", consumption.TotalRechargeAmount),       // 总充值金额
			fmt.Sprintf("%d", consumption.RefundAmount),              // 退款金额
			fmt.Sprintf("%f", consumption.TotalOrderPrice),           // 总订单价格
			fmt.Sprintf("%d", consumption.MonthlyOrderPaymentAmount), // 月度订单支付金额
		}
		if err := writer.Write(row); err != nil {
			return "", fmt.Errorf("写入CSV数据失败: %w", err)
		}
	}

	return "", nil
}

// GenerateFileName 生成导出文件名称
// dataType: 数据类型
// format: 导出格式
// 返回值: 生成的文件名
func GenerateFileName(dataType string, format ExportFormat) string {
	now := time.Now().Format("20060102_150405")
	extension := "csv"
	if format == FormatExcel {
		extension = "xlsx"
	}
	return fmt.Sprintf("%s_export_%s.%s", dataType, now, extension)
}
